import { root, node, NodeTypes, textNode } from "./ast";

/**节点处理函数数组*/
type nodeTransforms = Array<(node: node) => void>

/**Transform专用的上下文context */
interface context {
    /**根节点*/
    root: root,
    /**节点处理函数数组，可以对节点进行处理*/
    nodeTransforms: nodeTransforms,

}

/**transform函数第二个参数的类型 */
interface transformOptions {
    /**给node节点处理的函数数组 */
    nodeTransforms?: nodeTransforms
}
/**转换函数
 * @param root ast根节点
 * @param options 配置项
 */
export function transform(root: root, options?: transformOptions) {
    const context = createTransformContext(root, options)
    traverseNode(root, context)
    createRootCodegen(root)
}

/**深度优先搜索，递归节点进行遍历，调用 nodeTransforms 给节点进行处理
 * @param node 节点
 * @param context 上下文
 */
function traverseNode(node: node, context: context) {
    const { nodeTransforms } = context
    for (let i = 0; i < nodeTransforms.length; i++) {//给节点进行处理
        const fn = nodeTransforms[i];
        fn(node)
    }
    traverseChildren(node, context)

}
/**深度优先搜索，递归节点进行遍历
 * @param node 节点
 * @param context 上下文
 */
function traverseChildren(node: node, context: context) {
    const { children } = node
    if (children) {
        for (let i = 0; i < children.length; i++) {//递归每个节点
            const childNode = children[i];
            traverseNode(childNode, context)
        }
    }
}
/**给root的codegenNode赋值 */
function createRootCodegen(root: root) {
    root.codegenNode = root.children[0]
}


/**创建Transform专用的上下文context */
function createTransformContext(root: root, options?: transformOptions): context {
    const context: context = {
        root,
        nodeTransforms: options?.nodeTransforms || []
    }
    return context
}



